<template>
    <NuxtLayout name="default">
        <div class="flex flex-1 gap-4 overflow-hidden">
            <div class="mcp-tools">
                <div class="bg-body border border-lighter rounded-lg">
                    <div class="flex justify-end border-b border-light p-3">
                        <el-button
                            type="primary"
                            :icon="Setting"
                            :loading="loading"
                            @click="handleSubmit"
                        >
                            保存
                        </el-button>
                        <el-button
                            :icon="Connection"
                            @click="teamPopup = true"
                        >协作</el-button>
                        <el-button :icon="Delete">删除</el-button>
                    </div>
                    <el-form
                        class="p-4 pb-0"
                        :model="formData"
                        :rules="formRules"
                        label-position="right"
                        label-width="50px"
                    >
                        <el-form-item label="图标" prop="logo">
                            <upload-single
                                v-model="formData.logo"
                                size="80px"
                                tips-text="上传图标"
                            />
                        </el-form-item>
                        <el-form-item label="名称" prop="name">
                            <el-input
                                v-model="formData.name"
                                placeholder="给MCP设置一个名称"
                                maxlength="100"
                            />
                        </el-form-item>
                        <el-form-item label="简介" prop="intro">
                            <el-input
                                v-model="formData.intro"
                                placeholder="给您的MCP一个简介"
                                type="textarea"
                                :rows="3"
                                maxlength="2000"
                                show-word-limit
                            />
                        </el-form-item>
                    </el-form>
                </div>

                <div class="mcp-tools-parse">
                    <el-scrollbar ref="scrollRef" height="100%">
                        <div class="p-5">
                            <div class="text-tx-regular font-semibold py-2">MCP地址</div>
                            <div class="flex items-center w-full">
                                <el-input
                                    v-model="formData.url"
                                    placeholder="请输入MCP地址"
                                    class="flex-1 mr-2"
                                />

                                <el-button
                                    class="!w-[60px] !h-[38px]"
                                    :disabled="parserLoading"
                                    @click="handleParser"
                                >
                                    <span v-if="!parserLoading">解析</span>
                                    <icon
                                        v-else
                                        name="el-icon-Loading"
                                        class="is-loading"
                                    />
                                </el-button>
                            </div>

                            <div class="text-tx-regular font-semibold pt-2 mt-4">
                                工具列表
                                <span v-if="formData.tools.length > 0">
                                    ({{ formData.tools.length }})
                                </span>
                            </div>
                            <ul class="tools-list">
                                <li
                                    v-for="(item, index) in formData.tools"
                                    :key="index"
                                    :class="{active: parserIndex === index}"
                                    @click="handleSelect(index)"
                                >
                                    <el-tag type="info">{{ index + 1 }}</el-tag>
                                    <dl class="grid flex-1">
                                        <dt class="mb-1 truncate">{{ item.name }}</dt>
                                        <dd class="text-xs text-tx-placeholder truncate">
                                            {{ item.description }}
                                        </dd>
                                    </dl>
                                    <el-switch
                                        v-model="item.is_enable"
                                        inline-prompt
                                        active-text="开"
                                        inactive-text="关"
                                    />
                                </li>
                            </ul>
                        </div>
                    </el-scrollbar>
                </div>
            </div>

            <div class="mcp-debug">
                <h3 class="text-2xl font-bold p-4">调试预览</h3>
                <el-scrollbar ref="scrollbarRef" height="100%">
                    <div class="grid p-4 pt-0">
                        <div class="p-4 bg-lighter rounded-lg">
                            <dl>
                                <dt class="font-semibold text-tx-regular">
                                    {{ formData.tools[parserIndex]?.name }}
                                </dt>
                                <dd class="text-xs text-tx-placeholder mt-1">
                                    {{ formData.tools[parserIndex]?.description }}
                                </dd>
                            </dl>
                        </div>

                        <el-form
                            v-if="!validateUtil.isEmptyObject(parserInput)"
                            class="border rounded-lg p-4 mt-4"
                            label-position="top"
                        >
                            <el-form-item
                                v-for="(item, key) in (parserInput as McpToolsParams)"
                                :key="key"
                                :required="parserRequired.includes(String(key))"
                            >
                                <template #label>
                                    <div class="inline-block">
                                        <span class="mr-1">{{ key }}</span>
                                        <el-tooltip v-if="item.description" placement="top">
                                            <icon name="svg-icon-Question" class="align-middle" />
                                            <template #content>
                                                {{ item.description }}
                                            </template>
                                        </el-tooltip>
                                    </div>
                                </template>
                                <template v-if="item.type === 'number'">
                                    <el-input v-model="item.value" type="number" />
                                </template>
                                <template v-if="item.type === 'string'">
                                    <el-input
                                        v-model="item.value"
                                        type="textarea"
                                        :placeholder="item.description"
                                        :rows="3"
                                    />
                                </template>
                                <template v-if="item.type === 'array'">
                                    <el-input
                                        v-model="item.value"
                                        type="textarea"
                                        :rows="3"
                                    />
                                </template>
                            </el-form-item>
                        </el-form>

                        <div v-if="!validateUtil.isEmptyObject(parserInput)" class="mt-4">
                            <el-button
                                class="!w-[60px]"
                                type="primary"
                                :disabled="runToolLoading"
                                @click="callTool"
                            >
                                <span v-if="!runToolLoading">运行</span>
                                <icon
                                    v-else
                                    name="el-icon-Loading"
                                    class="is-loading"
                                />
                            </el-button>
                        </div>

                        <div v-if="runToolResults" class="mt-4 grid">
                            <markdown :content="runToolResults"  />
                        </div>
                    </div>
                </el-scrollbar>
            </div>
        </div>

        <popup-team-cfg
            v-if="teamPopup"
            type="mcp"
            :show="teamPopup"
            :code="formData.code"
            :power="formData.power"
            @close="teamPopup = false"
        />
    </NuxtLayout>
</template>

<script lang="ts" setup>
import { Connection, Delete, Setting } from '@element-plus/icons-vue'
import validateUtil from '~/utils/validate'
import mcpClientApi from '~/api/agent/mcp/client'
import PopupTeamCfg from '../_components/popup-team-cfg.vue'

const route = useRoute()
const mcpCode = String(route.params.code)

// 团队弹窗
const teamPopup = ref<boolean>(false)

// 解析数据
const parserUrl = ref<string>('')
const parserIndex = ref<number>(0)
const parserInput = ref<McpToolsParams>({})
const parserLoading = ref<boolean>(false)
const parserRequired = ref<string[]>([])

// 运行调试
const runToolResults = ref<string>('')
const runToolLoading = ref<boolean>(false)

// 基础表单
const loading = ref<boolean>(false)
const formData = reactive<McpDetailResponse>({
    code: '',
    logo: '',
    name: '',
    intro: '',
    url: '',
    power: 0,
    is_owner: false,
    tools: [] as McpToolsResponse[]
})


// 表单规则
const formRules: any = reactive({
    logo: [
        { required: true, message: 'MCP图标不能为空', trigger: 'blur' },
        { max: 250, message: 'MCP图标链接不能大于250个字符', trigger: 'blur' }
    ],
    name: [
        { required: true, message: 'MCP名称不能为空', trigger: 'blur' },
        { max: 32, message: 'MCP名称不能大于100个字符', trigger: 'blur' }
    ]
})

/**
 * 获取工具
 */
const handleParser = async () => {
    if (!formData.url) {
        return feedback.msg('请输入MCP地址')
    }

    try {
        parserLoading.value = true
        formData.tools = await mcpClientApi.get_tools(formData.url)
            .finally(() => {
                parserLoading.value = false
            })
        parserUrl.value = formData.url
        handleSelect(0)
    } catch {}
}

/**
 * 选择工具
 *
 * @param {number} index
 */
const handleSelect = (index: number) => {
    parserIndex.value = index
    parserRequired.value = formData.tools[index].inputSchema.required || []
    const properties = formData.tools[index].inputSchema.properties
    parserInput.value = Object.entries(properties)
        .reduce((acc: any, [key, value]) => {
            acc[key] = {
                value: '',
                ...value
            }
            return acc
        }, {})
}

/**
 * 保存信息
 */
const handleSubmit = async () => {
    if (formData.tools.length <= 0) {
        return feedback.msgError('请至少需要有一个工具存在!')
    }

    let enable = false
    for (let i = 0; i < formData.tools.length; i++) {
        if (formData.tools[i].is_enable) {
            enable = true
            break
        }
    }

    if (!enable) {
        return feedback.msgError('请至少保证有一个工具是启用状态!')
    }

    loading.value = true
    await mcpClientApi.edit(formData)
        .finally(() => {
            loading.value = false
        })
    feedback.msgSuccess('保存成功')
}

/**
 * 运行工具
 */
const callTool = async () => {
    const toolArgs: Record<string, any> = {}
    Object.entries(parserInput.value).forEach(([k, v]) => {
        const vl: any = v
        if (vl.value) {
            toolArgs[k] = vl.value
        }
    })

    if (parserRequired.value.length > 0) {
        const keys = Object.keys(toolArgs)
        for (let i = 0; i < parserRequired.value.length; i++) {
            const v = parserRequired.value[i]
            if (!keys.includes(v)) {
                return feedback.msgError(v + ' 参数为必填项')
            }
        }
    }

    runToolLoading.value = true
    const toolName: string = formData.tools[parserIndex.value].name
    const results = await mcpClientApi.call_tool({
        url: parserUrl.value,
        tool_name: toolName,
        tool_args: toolArgs
    }).finally(() => {
        runToolLoading.value = false
    })

    const jsonStr: string = JSON.stringify(results, null, 4)
    runToolResults.value = '```json\n' + jsonStr + '\n```'
}

watch(
    () => mcpCode,
    async (value) => {
        if (value) {
            const data: McpDetailResponse = await mcpClientApi.detail(mcpCode)
            formData.code = data.code
            formData.logo = data.logo
            formData.name = data.name
            formData.intro = data.intro
            formData.url = data.url
            formData.tools = data.tools
            parserUrl.value = data.url
            handleSelect(0)
        }
    }, { immediate: true }
)
</script>

<style lang="scss" scoped>
.mcp-tools {
    display: flex;
    flex-direction: column;
    width: 35%;
    min-width: 600px;
    .mcp-tools-parse {
        flex: 1;
        margin-top: 10px;
        overflow: hidden;
        background-color: var(--el-bg-color);
        border: 1px solid var(--el-border-color-lighter);
        border-radius: 8px;
        .tools-list {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-top: 10px;
            li {
                display: flex;
                gap: 10px;
                align-items: center;
                padding: 10px;
                cursor: pointer;
                border: 1px solid transparent;
                border-bottom-color: var(--el-border-color-lighter);
                border-radius: 6px;
                &.active {
                    border-color: var(--el-color-primary);
                }
            }
        }
    }
}

.mcp-debug {
    display: flex;
    flex: 1;
    flex-direction: column;
    background-color: var(--el-bg-color);
    border: 1px solid var(--el-border-color-lighter);
    border-radius: 8px;
}
</style>
